home *** CD-ROM | disk | FTP | other *** search
/ Amiga CD32 Gamer 22 / CD32 Gamer - 1996 - Issue 22.iso / fli / src / c2p_040.s < prev    next >
Text File  |  1995-01-03  |  9KB  |  396 lines

  1. ; Chunky2Planar algorithm, originally by James McCoull
  2. ; Modified by Peter McGavin for variable size and depth
  3. ; and "dirty list" (hope I didn't slow it down too much)
  4. ;
  5. ;     Cpu only solution VERSION 2
  6. ;    Optimised for 040+fastram
  7. ;    bitplanes are assumed contiguous!
  8. ;    analyse instruction offsets to check performance
  9.  
  10. ;void __asm c2p_8_040 (register __a0 UBYTE *chunky_data,
  11. ;                      register __a1 PLANEPTR raster,
  12. ;                      register __a2 UBYTE *dirty_list,
  13. ;                      register __d1 ULONG plsiz);
  14.  
  15. ; a0 -> width*height chunky pixels
  16. ; a1 -> contiguous bitplanes
  17. ; a2 -> dirty list (1-byte flag for whether each 32 pixel "unit" needs updating)
  18. ; d1 = width*height/8   (width*height must be a multiple of 32)
  19.  
  20.     ifeq    depth-8
  21.         xdef    _c2p_8_040
  22. _c2p_8_040:
  23.     else
  24.     ifeq    depth-6
  25.         xdef    _c2p_6_040
  26. _c2p_6_040:
  27.     else
  28.     ifeq    depth-4
  29.         xdef    _c2p_4_040
  30. _c2p_4_040:
  31.     else
  32.         fail    "unsupported depth!"
  33.     endc
  34.     endc
  35.     endc
  36.  
  37. merge        macro ; in1,in2,tmp3,tmp4,mask,shift
  38. ; \1 = abqr
  39. ; \2 = ijyz
  40.         move.l    \2,\4
  41.         move.l    #\5,\3
  42.         and.l    \3,\2    ; \2 = 0j0z
  43.         and.l    \1,\3    ; \3 = 0b0r
  44.         eor.l    \3,\1    ; \1 = a0q0
  45.         eor.l    \2,\4    ; \4 = i0y0
  46.         ifeq    \6-1
  47.         add.l    \3,\3
  48.         else
  49.         lsl.l    #\6,\3    ; \3 = b0r0
  50.         endc
  51.         lsr.l    #\6,\4    ; \4 = 0i0y
  52.         or.l    \3,\2    ; \2 = bjrz
  53.         or.l    \4,\1    ; \1 = aiqy
  54.         endm
  55.  
  56. merge4        macro ; in1,in2,tmp3,tmp4,mask
  57.     ifgt depth-4
  58.         merge    \1,\2,\3,\4,\5,4
  59.     else
  60.         move.l    #\5,\3    ; \3 = mask
  61.         and.l    \3,\2    ; \2 = 0j0z
  62.         and.l    \1,\3    ; \3 = 0b0r
  63.         lsl.l    #4,\3    ; \3 = b0r0
  64.         or.l    \3,\2    ; \2 = bjrz
  65.     endc
  66.         endm
  67.  
  68.  
  69. start:
  70. ;        jmp    next        ; self-modified code here
  71. ;next:
  72. ;        movem.l    d1/a0-a2,-(sp)
  73. ;; relocate c2p to a 16-aligned address
  74. ;        lea    (c2p,pc),a0
  75. ;        move.l    a0,d0
  76. ;        and.b    #%11110000,d0
  77. ;        move.l    d0,a1
  78. ;
  79. ;; patch jmp
  80. ;        move.l    d0,start+2
  81. ;        move.w    #(end-c2p)-1,d0
  82. ;loop:        move.b    (a0)+,(a1)+
  83. ;        dbra    d0,loop
  84. ;
  85. ;; flush cache
  86. ;        move.l    (4).w,a6
  87. ;        jsr    (_LVOCacheClearU,a6)
  88. ;
  89. ;; restore parameters and restart
  90. ;        movem.l    (sp)+,d1/a0-a2
  91. ;        bra.b    start
  92. ;
  93. ;        ds.w    8        ; space for relocation
  94.  
  95. ; the real c2p routine starts here
  96. c2p:
  97.         movem.l    d2-d7/a2-a6,-(sp)
  98.  
  99.         sub.w    #44,sp        ; space for temporary variables
  100.  
  101. ; a0 = chunky buffer
  102. ; a1 = output area
  103. ; a2 = dirty list
  104. ; d1 = plsiz
  105.  
  106.         movea.l    d1,a3        ; a3 = plsiz
  107.  
  108.         move.l    a0,a4
  109.         lsl.l    #3,d1
  110.         add.l    d1,a4        ; a4 -> end of chunky data
  111.  
  112. first_loop:    tst.l    (a2)+        ; do the next 128 pixels need updating?
  113.         bne.b    first_patch    ; branch if yes
  114.  
  115.         adda.w    #128,a0        ; skip 128 pixels on input
  116.         adda.w    #16,a1        ; skip 128 pixels on output
  117.  
  118.         cmpa.l    a0,a4
  119.         bcc.b    first_loop
  120.         bra.w    exit        ; exit if no changes found
  121.  
  122. first_patch:    subq.l    #4,a2        ; restore input address
  123.         tst.b    (a2)+        ; do the next 32 pixels need updating?
  124.         bne.b    first_case    ; branch if yes
  125.         adda.w    #32,a0        ; skip 32 pixels on input
  126.         addq.l    #4,a1        ; skip 32 pixels on output
  127.         tst.b    (a2)+        ; do the next 32 pixels need updating?
  128.         bne.b    first_case    ; branch if yes
  129.         adda.w    #32,a0        ; skip 32 pixels on input
  130.         addq.l    #4,a1        ; skip 32 pixels on output
  131.         tst.b    (a2)+        ; do the next 32 pixels need updating?
  132.         bne.b    first_case    ; branch if yes
  133.         adda.w    #32,a0        ; skip 32 pixels on input
  134.         addq.l    #4,a1        ; skip 32 pixels on output
  135.         tst.b    (a2)+        ; do the next 32 pixels need updating?
  136.         bne.b    first_case    ; branch if yes
  137.         adda.w    #32,a0        ; skip 32 pixels on input
  138.         addq.l    #4,a1        ; skip 32 pixels on output
  139.         bra.b    first_loop    ; this should never happen
  140.  
  141. first_case:    move.l    (0,a0),d1
  142.          move.l    (4,a0),d3
  143.         move.l    (8,a0),d0
  144.         move.l    (12,a0),d2
  145.         move.l    (2,a0),d4
  146.          move.l    (10,a0),d5
  147.         move.l    (6,a0),d6
  148.         move.l    (14,a0),d7
  149.  
  150.          move.w    (16,a0),d1
  151.          move.w    (24,a0),d0
  152.         move.w    (20,a0),d3
  153.         move.w    (28,a0),d2
  154.          move.w    (18,a0),d4
  155.          move.w    (26,a0),d5
  156.         move.w    (22,a0),d6
  157.         move.w    (30,a0),d7
  158.  
  159.         adda.w    #32,a0
  160.  
  161.         move.l    d6,a5
  162.         move.l    d7,a6
  163.  
  164.         merge    d1,d0,d6,d7,$00ff00ff,8
  165.         merge    d3,d2,d6,d7,$00ff00ff,8
  166.  
  167.         merge4    d1,d3,d6,d7,$0f0f0f0f,4    
  168.         merge4    d0,d2,d6,d7,$0f0f0f0f,4
  169.  
  170.         exg    d1,a5
  171.         exg    d0,a6
  172.  
  173.         merge    d4,d5,d6,d7,$00ff00ff,8
  174.         merge    d1,d0,d6,d7,$00ff00ff,8
  175.  
  176.         merge4    d4,d1,d6,d7,$0f0f0f0f,4
  177.         merge4    d5,d0,d6,d7,$0f0f0f0f,4
  178.  
  179.         merge    d3,d1,d6,d7,$33333333,2
  180.         merge    d2,d0,d6,d7,$33333333,2    
  181.  
  182.         merge    d3,d2,d6,d7,$55555555,1
  183.         merge    d1,d0,d6,d7,$55555555,1
  184.  
  185.         move.l    d0,(0*4,sp)        ;plane0 (movem.l is slower!)
  186.         move.l    d1,(1*4,sp)        ;plane1
  187.         move.l    d2,(2*4,sp)        ;plane2
  188.         move.l    d3,(3*4,sp)        ;plane3
  189.  
  190.     ifgt depth-4
  191.  
  192.         move.l    a5,d3
  193.         move.l    a6,d2
  194.  
  195.         merge    d3,d4,d6,d7,$33333333,2
  196.         merge    d2,d5,d6,d7,$33333333,2
  197.  
  198.     ifgt depth-6
  199.         merge    d3,d2,d6,d7,$55555555,1
  200.     endc
  201.         merge    d4,d5,d6,d7,$55555555,1
  202.  
  203.         move.l    d5,(4*4,sp)        ;plane4
  204.         move.l    d4,(5*4,sp)        ;plane5
  205.  
  206.     ifgt depth-6
  207.         move.l    d2,(6*4,sp)        ;plane6
  208.         move.l    d3,(7*4,sp)        ;plane7
  209.     endc
  210.  
  211.     endc
  212.  
  213.         move.l    a1,(32,sp)        ; save output address
  214.         addq.l    #4,a1            ; skip 32 pixels on output
  215.  
  216.         cmpa.l    a0,a4
  217.         beq.w    final_case
  218.  
  219.  
  220. main_loop:    tst.l    (a2)+        ; do the next 128 pixels need updating?
  221.         bne.b    main_patch    ; branch if yes
  222.  
  223.         adda.w    #128,a0        ; skip 128 pixels on input
  224.         adda.w    #16,a1        ; skip 128 pixels on output
  225.  
  226.         cmpa.l    a0,a4
  227.         bcc.b    main_loop
  228.         bra.w    final_case    ; exit if no changes found
  229.  
  230. main_patch:    subq.l    #4,a2        ; restore input address
  231.         tst.b    (a2)+        ; do the next 32 pixels need updating?
  232.         beq.b    1$        ; branch if no
  233.         bsr.b    main_case
  234. 1$:        adda.w    #32,a0        ; skip 32 pixels on input
  235.         addq.l    #4,a1        ; skip 32 pixels on output
  236.         tst.b    (a2)+        ; do the next 32 pixels need updating?
  237.         beq.b    2$        ; branch if no
  238.         bsr.b    main_case
  239. 2$:        adda.w    #32,a0        ; skip 32 pixels on input
  240.         addq.l    #4,a1        ; skip 32 pixels on output
  241.         tst.b    (a2)+        ; do the next 32 pixels need updating?
  242.         beq.b    3$        ; branch if no
  243.         bsr.b    main_case
  244. 3$:        adda.w    #32,a0        ; skip 32 pixels on input
  245.         addq.l    #4,a1        ; skip 32 pixels on output
  246.         tst.b    (a2)+        ; do the next 32 pixels need updating?
  247.         beq.b    4$        ; branch if no
  248.         bsr.b    main_case
  249. 4$:        adda.w    #32,a0        ; skip 32 pixels on input
  250.         addq.l    #4,a1        ; skip 32 pixels on output
  251.         cmpa.l    a0,a4
  252.         bcc.b    main_loop
  253.         bra.w    final_case    ; exit if no changes found
  254.  
  255. main_case:
  256.         move.l    a1,(36+4,sp)    ; save current output address
  257.         move.l    (32+4,sp),a1    ; a1 = previous output address
  258.  
  259.         move.l    (0,a0),d1
  260.          move.l    (4,a0),d3
  261.          move.l    (8,a0),d0
  262.         move.l    (12,a0),d2
  263.         move.l    (2,a0),d4
  264.          move.l    (10,a0),d5
  265.         move.l    (6,a0),d6
  266.         move.l    (14,a0),d7
  267.  
  268.          move.w    (16,a0),d1
  269.          move.w    (24,a0),d0
  270.         move.w    (20,a0),d3
  271.         move.w    (28,a0),d2
  272.          move.w    (18,a0),d4
  273.          move.w    (26,a0),d5
  274.         move.w    (22,a0),d6
  275.         move.w    (30,a0),d7
  276.  
  277.         move.l    d6,a5
  278.         move.l    d7,a6
  279.  
  280.         move.l    (0*4+4,sp),(a1)        ;plane0
  281.         adda.l    a3,a1            ;a1+=plsiz
  282.  
  283.         merge    d1,d0,d6,d7,$00ff00ff,8
  284.         merge    d3,d2,d6,d7,$00ff00ff,8
  285.  
  286.         move.l    (1*4+4,sp),(a1)        ;plane1
  287.         adda.l    a3,a1            ;a1+=plsiz
  288.  
  289.         merge    d1,d3,d6,d7,$0f0f0f0f,4    
  290.         merge    d0,d2,d6,d7,$0f0f0f0f,4
  291.  
  292.         exg    d1,a5
  293.         exg    d0,a6
  294.  
  295.         move.l    (2*4+4,sp),(a1)        ;plane2
  296.         adda.l    a3,a1            ;a1+=plsiz
  297.  
  298.         merge    d4,d5,d6,d7,$00ff00ff,8
  299.         merge    d1,d0,d6,d7,$00ff00ff,8
  300.  
  301.         move.l    (3*4+4,sp),(a1)        ;plane3
  302.         adda.l    a3,a1            ;a1+=plsiz
  303.  
  304.         merge    d4,d1,d6,d7,$0f0f0f0f,4
  305.         merge    d5,d0,d6,d7,$0f0f0f0f,4
  306.  
  307.     ifgt depth-4
  308.         move.l    (4*4+4,sp),(a1)        ;plane4
  309.         adda.l    a3,a1            ;a1+=plsiz
  310.     endc
  311.  
  312.         merge    d3,d1,d6,d7,$33333333,2
  313.         merge    d2,d0,d6,d7,$33333333,2    
  314.  
  315.     ifgt depth-4
  316.         move.l    (5*4+4,sp),(a1)        ;plane5
  317.         adda.l    a3,a1            ;a1+=plsiz
  318.     endc
  319.  
  320.         merge    d3,d2,d6,d7,$55555555,1
  321.         merge    d1,d0,d6,d7,$55555555,1
  322.  
  323.         move.l    d0,(0*4+4,sp)        ;plane0 (movem.l is slower!)
  324.         move.l    d1,(1*4+4,sp)        ;plane1
  325.         move.l    d2,(2*4+4,sp)        ;plane2
  326.         move.l    d3,(3*4+4,sp)        ;plane3
  327.  
  328.     ifgt depth-4
  329.         move.l    a5,d3
  330.         move.l    a6,d2
  331.  
  332.     ifgt depth-6
  333.         move.l    (6*4+4,sp),(a1)        ;plane6
  334.         adda.l    a3,a1            ;a1+=plsiz
  335.     endc
  336.  
  337.         merge    d3,d4,d6,d7,$33333333,2
  338.         merge    d2,d5,d6,d7,$33333333,2
  339.  
  340.     ifgt depth-6
  341.         move.l    (7*4+4,sp),(a1)        ;plane7
  342.         adda.l    a3,a1            ;a1+=plsiz
  343.     endc
  344.  
  345.     ifgt depth-6
  346.         merge    d3,d2,d6,d7,$55555555,1
  347.     endc
  348.         merge    d4,d5,d6,d7,$55555555,1
  349.  
  350.         move.l    d5,(4*4+4,sp)        ;plane4
  351.         move.l    d4,(5*4+4,sp)        ;plane5
  352.  
  353.     ifgt depth-6
  354.         move.l    d2,(6*4+4,sp)        ;plane6
  355.         move.l    d3,(7*4+4,sp)        ;plane7
  356.     endc
  357.  
  358.     endc
  359.  
  360.         movea.l    (36+4,sp),a1    ; restore current output address
  361.         move.l    a1,(32+4,sp)    ; save output address
  362.  
  363.         rts
  364.  
  365.  
  366. final_case:    move.l    (32,sp),a1    ; a1 = previous output address
  367.  
  368.         move.l    (0*4,sp),(a1)        ;plane0
  369.         adda.l    a3,a1            ;a1+=plsiz
  370.         move.l    (1*4,sp),(a1)         ;plane1
  371.         adda.l    a3,a1            ;a1+=plsiz
  372.         move.l    (2*4,sp),(a1)        ;plane2
  373.         adda.l    a3,a1            ;a1+=plsiz
  374.         move.l    (3*4,sp),(a1)        ;plane3
  375.     ifgt depth-4
  376.         adda.l    a3,a1            ;a1+=plsiz
  377.         move.l    (4*4,sp),(a1)        ;plane4    
  378.         adda.l    a3,a1            ;a1+=plsiz
  379.         move.l    (5*4,sp),(a1)        ;plane5
  380.     ifgt depth-6
  381.         adda.l    a3,a1            ;a1+=plsiz
  382.         move.l    (6*4,sp),(a1)        ;plane6
  383.         adda.l    a3,a1            ;a1+=plsiz
  384.         move.l    (7*4,sp),(a1)        ;plane7
  385.     endc
  386.     endc
  387.  
  388. exit:        add.w    #44,sp
  389.         movem.l    (sp)+,d2-d7/a2-a6
  390.         rts
  391.  
  392.         cnop    0,4
  393. end:
  394.  
  395.         end
  396.